﻿using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Media3D;
using Perspective.Wpf3D.Primitives;
using Perspective.Wpf3D.Sculptors;

namespace Perspective.Wpf3D.Shapes
{
    /// <summary>
    /// 组成管子的所有点和三角形集合
    /// A 3D pipe model.
    /// Default radius is 10.0.
    /// </summary>
    public class Pipe3D : PolygonalElement3D
    {
        #region Constructors
        /// <summary>
        /// Initializes a new instance of Concentric Pipe3D.
        /// </summary>
        public Pipe3D()
        {
        }
        #endregion

        #region Properties

        #region OuterRadius 外圆半径
        /// <summary>
        /// 外圆半径
        /// Gets or sets the pipe  outer circle radius.
        /// Default value is 1.0.
        /// </summary>
        public double OuterRadius
        {
            get { return (double)GetValue(OuterRadiusProperty); }
            set { SetValue(OuterRadiusProperty, value); }
        }

        /// <summary>
        /// Identifies the outer circle radius dependency property.
        /// </summary>
        public static readonly DependencyProperty OuterRadiusProperty =
            DependencyProperty.Register(
                "OuterRadius",
                typeof(double),
                typeof(Pipe3D),
                new UIPropertyMetadata(
                    PipeSculptor.DefaultOuterCircleRadius, 
                    VisualPropertyChanged),
                    PositiveDoubleValidateValue);
        #endregion

        #region InnerRadius 内圆半径
        /// <summary>
        /// 内圆半径
        /// Gets or sets the pipe inner circle radius.
        /// Default value is 1.0.
        /// </summary>
        public double InnerRadius
        {
            get { return (double)GetValue(InnerRadiusProperty); }
            set { SetValue(InnerRadiusProperty, value); }
        }

        /// <summary>
        /// Identifies the inner circle radius dependency property.
        /// </summary>
        public static readonly DependencyProperty InnerRadiusProperty =
            DependencyProperty.Register(
                "InnerRadius",
                typeof(double),
                typeof(Pipe3D),
                new UIPropertyMetadata(
                    PipeSculptor.DefaultInnerCircleRadius,
                    VisualPropertyChanged),
                    PositiveDoubleValidateValue);
        #endregion

        #region Height 高度

        /// <summary>
        /// 高度
        /// Gets or sets the model height.
        /// Default value is 1.0. Minimum value is 0.01.
        /// </summary>
        public double Height
        {
            get { return (double)GetValue(HeightProperty); }
            set { SetValue(HeightProperty, value); }
        }

        /// <summary>
        /// Identifies the Height dependency property.
        /// </summary>
        public static readonly DependencyProperty HeightProperty =
            DependencyProperty.Register(
                "Height",
                typeof(double),
                typeof(Pipe3D),
                new PropertyMetadata(
                    PipeSculptor.DefaultHeight,
                    VisualPropertyChanged),
                    HeightValidateValue);

        /// <summary>
        /// Validation of the Height value.
        /// </summary>
        /// <param name="value">Value to test.</param>
        /// <returns>Boolean value.</returns>
        public static bool HeightValidateValue(object value)
        {
            double i = (double)value;
            return i >= 0.001;
        }

        #endregion

        #region TexturePosition 纹理坐标位置

        /// <summary>
        /// 纹理坐标位置
        /// Gets or sets the position a a texture. Default is OnSides.
        /// </summary>
        public TexturePositions TexturePosition
        {
            get { return (TexturePositions)GetValue(TexturePositionProperty); }
            set { SetValue(TexturePositionProperty, value); }
        }

        /// <summary>
        /// Identifies the TexturePosition dependency property.
        /// </summary>
        public static readonly DependencyProperty TexturePositionProperty =
            DependencyProperty.Register(
            "TexturePosition", 
            typeof(TexturePositions),
            typeof(Pipe3D), 
            new PropertyMetadata(TexturePositions.OnSides));

        #endregion
        #endregion

        /// <summary>
        /// Called by UIElement3D.InvalidateModel() to update the 3D model.
        /// </summary>
        protected override void OnUpdateModel()
        {
            Sculptor = new PipeSculptor(OuterRadius, InnerRadius,Height, SideCount, InitialAngle, RoundingRate);
            base.OnUpdateModel();
        }
    }
}
